package com.yjd.pub.funds.service;

import com.yjd.comm.base.dao.IBaseDao;
import com.yjd.comm.base.enums.DbWREnums;
import com.yjd.comm.base.model.PagerModel;
import com.yjd.comm.base.service.impl.BaseServiceImpl;
import com.yjd.comm.funds.dto.FirstPayDto;
import com.yjd.comm.funds.dto.RechAddPriceDto;
import com.yjd.comm.funds.dto.RepaymentPayDto;
import com.yjd.comm.funds.enums.FundsIncomeEnum;
import com.yjd.comm.funds.enums.FundsRefTableEnum;
import com.yjd.comm.funds.enums.FundsTypeEnum;
import com.yjd.comm.funds.model.FundsModel;
import com.yjd.comm.funds.model.RechargeOrderModel;
import com.yjd.comm.funds.service.IFundsDataService;
import com.yjd.comm.funds.service.IFundsService;
import com.yjd.comm.util.ArithUtil;
import com.yjd.comm.util.FrameUtil;
import com.yjd.pub.funds.dao.IFundsDao;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * <b>description</b>：用户资金表业务实现<br>
 * <b>time</b>：2017-09-19 15:07:07 <br>
 * <b>author</b>：  carl
 */
@Service("fundsService")
public class FundsServiceImpl extends BaseServiceImpl implements IFundsService {

	/**
	 * 插入
	 * 
	 * @param model
	 * @return
	 * @throws Exception
	 */
	public FundsModel insert(FundsModel model) throws Exception {
		return this.fundsDao.insertModel(model, true);
	}

	/**
	 * 更新
	 * 
	 * @param model
	 * @return
	 * @throws Exception
	 */
	public int update(FundsModel model) throws Exception {
		return this.fundsDao.updateModel(model, true);
	}

	/**
	 * 根据id删除
	 * 
	 * @param user_id
	 * @return
	 * @throws Exception
	 */
	public int delete(long user_id) throws Exception {
		Map<Object, Object> paramMap = new HashMap<Object, Object>();
		paramMap.put("user_id", user_id);
		return this.fundsDao.deleteModel(paramMap, true);
	}

	/**
	 * 充值成功后账户余额增加
	 *
	 * @param orderModel
	 * @throws Exception
	 */
	@Override
	public void rechAddPrice(RechargeOrderModel orderModel,Long currtime) throws Exception {
		if(orderModel==null){
			FrameUtil.throwBaseException1("请求参数不能为空");
		}

		Double price = orderModel.getPrice();
		Long user_id = orderModel.getUser_id();

		if(price<=0){
			FrameUtil.throwBaseException1("金额不合法！");
		}

		if(user_id==null){
			FrameUtil.throwBaseException1("用户id不能为空");
		}

		if(currtime==null){
			FrameUtil.throwBaseException1("请求的更新时间不能为空！");
		}

		FundsModel fundsModel = this.fundsDao.getModelById(user_id,true);
		if(fundsModel==null){
			FrameUtil.throwBaseException1("用户资金账户不存在");
		}

		//更新用户账户资金
		if(this.fundsDao.rechAddPrice(new RechAddPriceDto(price,currtime,user_id,fundsModel.getVersion()))!=1){
			FrameUtil.throwBaseException1("更新资金失败，请重试！");
		}

		//新增资金流水
		fundsDataService.insertFundsData(user_id,price, ArithUtil.add(fundsModel.getAvailable(),price), FundsIncomeEnum.ADD,
				FundsTypeEnum.RECH,orderModel.getOrder_id().toString(), FundsRefTableEnum.MFQ_RECHARGE_ORDER,currtime);
	}


	/**
	 * 用户首付扣款
	 *
	 * @param user_id
	 * @param price
	 * @param ref_id
	 * @param currtime
	 * @throws Exception
	 */
	@Override
	public void firstPay(Long user_id, Double price, String ref_id, Long currtime) throws Exception {
		if(price<=0){
			FrameUtil.throwBaseException1("金额不合法！");
		}

		if(user_id==null){
			FrameUtil.throwBaseException1("用户id不能为空");
		}

		if(currtime==null){
			FrameUtil.throwBaseException1("请求的更新时间不能为空！");
		}

		FundsModel fundsModel = this.fundsDao.getModelById(user_id,true);
		if(fundsModel==null){
			FrameUtil.throwBaseException1("用户资金账户不存在");
		}
		if(price>fundsModel.getAvailable()){
			FrameUtil.throwBaseException1("账户可用余额不够");
		}

		if(this.fundsDao.firstPayReducePrice(new FirstPayDto(user_id,price,currtime,fundsModel.getVersion()))!=1){
			FrameUtil.throwBaseException1("更新资金失败，请重试！");
		}
		//新增资金流水
		fundsDataService.insertFundsData(user_id,price, ArithUtil.sub(fundsModel.getAvailable(),price), FundsIncomeEnum.REDUCE,
				FundsTypeEnum.FIRST_PAY,ref_id, FundsRefTableEnum.MFQ_ORDER,currtime);

	}


	/**
	 *  用户还款扣款
	 * @param user_id 用户id
	 * @param price 用户应还款金额
	 * @param ref_id  关联id
	 * @param overdue_price 罚息金额
	 * @param discount_amount  减免金额
	 * @throws Exception
	 */
	public void repaymentPay(Long user_id,Double price,Double overdue_price,Double discount_amount,Double interest,String ref_id,Long currtime) throws Exception {
		if(user_id==null){
			FrameUtil.throwBaseException1("用户id不能为空");
		}

		if(price<=0){
			FrameUtil.throwBaseException1("金额不合法！");
		}

		if(overdue_price<0){
			FrameUtil.throwBaseException1("罚息金额不合法！");
		}


		if(interest==null){
			FrameUtil.throwBaseException1("当前利息金额不能为空！");
		}

		if(discount_amount<0){
			FrameUtil.throwBaseException1("减免金额不合法！");
		}

		if(currtime==null){
			FrameUtil.throwBaseException1("请求的更新时间不能为空！");
		}

		FundsModel fundsModel = this.fundsDao.getModelById(user_id,true);
		if(fundsModel==null){
			FrameUtil.throwBaseException1("用户资金账户不存在");
		}
		if(price>fundsModel.getAvailable()){
			FrameUtil.throwBaseException1("资金账户可用余额不够");
		}
		int penalty_num = overdue_price>0?1:0;//

		if(this.fundsDao.repaymentPayReducePrice(new RepaymentPayDto(user_id,ArithUtil.sub(ArithUtil.add(price,overdue_price),discount_amount),currtime,
				penalty_num,overdue_price,price,interest,discount_amount,fundsModel.getVersion()))!=1){
			FrameUtil.throwBaseException1("更新资金失败，请重试！");
		}
		//新增资金流水(还款金额)
		Double trans_price = ArithUtil.sub(price,discount_amount);
		fundsDataService.insertFundsData(user_id,trans_price, ArithUtil.sub(fundsModel.getAvailable(),trans_price), FundsIncomeEnum.REDUCE,
				FundsTypeEnum.REPAYMENT,ref_id, FundsRefTableEnum.MFQ_REPAYMENT_DATA,currtime);

		Double overdue = ArithUtil.sub(overdue_price,discount_amount);
		if (overdue>0){
			//新增资金流水(实际罚息金额)
			fundsDataService.insertFundsData(user_id,overdue, ArithUtil.sub(fundsModel.getAvailable(),overdue), FundsIncomeEnum.REDUCE,
					FundsTypeEnum.OVERDUE,ref_id, FundsRefTableEnum.MFQ_REPAYMENT_DATA,currtime);
		}


	}

	@Override
	public int increasePrice(Map<String, Object> paramMap) throws Exception {
		return this.fundsDao.increasePrice(paramMap);
	}

	@Override
	public PagerModel queryUserFunds(Map<String, Object> paramMap, DbWREnums write) throws Exception {
		return this.getPageModel(paramMap, "queryUserFunds", this.getBaseDao(), write);
	}

	@Override
	public void paymentRefund(Long user_id, Double payment, Long order_id) throws Exception {

		FundsModel fundsModel = this.fundsDao.getModelById(user_id, DbWREnums.WRITE.isWrite());
		if(fundsModel==null){
			FrameUtil.throwBaseException1("用户资金账户不存在");
		}

		int count = fundsDao.increasePrice(FrameUtil.newHashMap(
				"user_id", fundsModel.getUser_id(),
				"where_version", fundsModel.getVersion(),
				"available", payment ));
		if (count != 1) {
			FrameUtil.throwBaseException1("更新用户资金失败");
		}

		// 记录退款流水
		Double balance = ArithUtil.add(fundsModel.getAvailable(), payment);
		fundsDataService.insertFundsData(fundsModel.getUser_id(), payment, balance,
				FundsIncomeEnum.ADD, FundsTypeEnum.REFUND, order_id.toString(), FundsRefTableEnum.MFQ_ORDER, FrameUtil.getTime());
	}

    /**
     * 更新用户资金
     *
     * @param user_id
     * @param param
     * @throws Exception
     */
    @Override
    public int updatByMap(Long user_id, Map param) throws Exception {
        if(user_id==null){
            FrameUtil.throwBaseException1("用户id不能为空");
        }

        if(param==null){
            FrameUtil.throwBaseException1("请求参数不能为空");
        }
        param.put("user_id",user_id);
       return this.fundsDao.updateByMap(param,true);

    }

	/**
	 * 商户确认退单更新资金情况
	 *
	 * @param paramMap
	 * @return
	 * @throws Exception
	 */
	@Override
	public int addPriceOfOrderRturn(Map<String, Object> paramMap) throws Exception {
		return this.fundsDao.addPriceOfOrderRturn(paramMap);
	}

	@Resource
	private IFundsDao fundsDao;

	@Resource
	private IFundsDataService fundsDataService;

	@Override
	public IBaseDao getBaseDao() {
		return this.fundsDao;
	}

}
